package utils

import (
	"distributed_db/utils/db"
)

// TODO 错误类型需要做明确的区分
const (
	OK                     = "OK"
	ErrNoKey               = "ErrNoKey"
	ErrWrongLeader         = "ErrWrongLeader"
	ErrNotReady            = "ErrNotReady"
	ErrNoSuchTableInMemory = "ErrNoSuchTableInMemory"
	ErrMasterNotReady      = "ErrMasterNotReady"
	ErrDeleteTable         = "ErrDeleteTable"
	ErrInsertData          = "ErrInsertData"
	ErrDeleteData          = "ErrDeleteData"
	ErrTimeWait            = "ErrTimeWait"
)

type Err string

type InsertRegionArgs struct {
	TxID        string
	Table       string
	Columns     []string
	PrimaryKeys []string
	Indexes     []string
	Values      [][]interface{}
}

type InsertRegionReply struct {
	Ans int
	Err error
}

type QueryRegionArgs struct {
	TxID  string
	Table string
	Row   string
	Cond  string
}

type QueryRegionReply struct {
	Data []map[string]interface{}
	Err  error
}

type DeleteRegionArgs struct {
	TxID  string
	Table string
	Cond  string
}

type DeleteRegionReply struct {
	Ans int
	Err error
}

type UpdateRegionArgs struct {
	TxID   string
	Table  string
	Clause string
	Cond   string
}

type UpdateRegionReply struct {
	Err error
}

type GetRegionDataArgs struct {
	Table string
}
type GetRegionDataReply struct {
	Cols []string
	Data [][]interface{}
	Err  error
}

type GetAllRegionsArgs struct {
}

type GetAllRegionsReply struct {
	Regions []db.Region
	Err     error
}

type DropRegionArgs struct {
	Region string
}

type DropRegionReply struct {
	Err error
}

type DropAllRegionsArgs struct {
}

type DropAllRegionsReply struct {
	Err error
}

type CreateIndexArgs struct {
	Table   string
	Indexes []string
}

type CreateIndexReply struct {
	Err error
}

// Put or Append
type PutAppendArgs struct {
	Key      string
	Value    string
	Op       string // "Put" or "Append"
	ClientId int64  // Clerk 的 id
	EntryId  uint32 // RPC 操作的 id
}

type PutAppendReply struct {
	Err Err
}

type GetArgs struct {
	Key      string
	ClientId int64
	EntryId  uint32
}

type GetReply struct {
	Err   Err
	Value string
}

// 更新缓存的结构体
// 需要用到需要更新缓存的tablename切片
type UpdateCacheArgs struct {
	// 需要更新的表名
	TableNames []string
	// 用于保证一致性
	ClientId int64
	EntryId  uint32
}

type UpdateCacheReply struct {
	// region1  ----  [(localhost:8000, 11), (localhost:8001, 11), (localhost:8002, 11)]
	// region2  ----  [(localhost:8003, 11), (localhost:8004, 11), (localhost:8005, 11)]
	RegionServers map[string]map[string]int

	// 客户端缓存的生存时间
	TTL int64

	// 错误
	Err Err
}

type CreateTableArgs struct {
	TableName string
	Cols      map[string]string
	ClientId  int64
	EntryId   uint32
}

type CreateTableReply struct {
	RegionServers []string
	Err           Err
}

type DropTableArgs struct {
	TableName string
	ClientId  int64
	EntryId   uint32
}

type DropTableReply struct {
	Err Err
}

type InsertDataArgs struct {
	TableName string
	Data      map[string]string
	ClientId  int64
	EntryId   uint32
}

type InsertDataReply struct {
	Rows int64
	Err  Err
}

type DeleteDataArgs struct {
	Key       string
	TableName string
	ClientId  int64
	EntryId   uint32
}

type DeleteDataReply struct {
	Rows int64
	Err  Err
}
